﻿using System;
using System.Linq;
using System.Drawing;
using System.Collections.Generic;
using System.Windows.Forms;
using Syncfusion.Windows.Forms.Tools;

using PMngr.Data;

namespace PMngr.Main
{
    public partial class EditControl : BaseControl
    {
        private IRepositoryFactory _repositoryFactory;
        private int? _profileId;
        // 原单位性质，单位区域
        private string _originInUnitType;
        private string _originOutUnitType;
        private string _originInUpUnit;
        private string _originInUnitKind;
        private string _originOutUnitKind;
        private string _originOutUpUnit;
        
        public EditControl()
        {
            InitializeComponent();
            
            InitializeCalendar();
           
            collapsePrimitive1.BackColor = Color.Transparent;
            collapsePrimitive2.BackColor = Color.Transparent;
            collapsePrimitive1.BorderColor = Color.Transparent;
            collapsePrimitive2.BorderColor = Color.Transparent;            
        }

        public void Initialize(IRepositoryFactory repositoryFactory)
        {
            _repositoryFactory = repositoryFactory;
            InitializeControls();
        }

        public void Initialize(IRepositoryFactory repositoryFactory, int userId)
        {
            Initialize(repositoryFactory);
            _profileId = userId;

            InitializeUpdateView();
        }

        public override void InitializeControls()
        {            
            InitializeDropDownList();
            RdoCheckChanged(this, EventArgs.Empty);
        }

        private void DropDownListImpl(string type, ComboBoxBaseDataBound control)
        {
            using (var repository = _repositoryFactory.CreateRepository())
            {
                var options = repository.All<ItemBase>();
                var datasource = from o in options
                                 where o.Type == type && o.IsValid
                                 orderby o.Order
                                 select new {o.Code, o.Name};
                var result = datasource.ToList();
                result.Insert(0, new {Code = DefaultNull.DefaultValue, Name = DefaultNull.DefaultName});
                control.DataSource = result;
                control.DisplayMember = "Name";
                control.ValueMember = "Code";
            }
        }

        private void InitializeCalendar()
        {
            dtBirthdate.IsNullDate = true;
            dtMD.IsNullDate = true;
            dtWorkStart.IsNullDate = true;
            dtRecordDate.Value = DateTime.Now;
            //
            dtBirthdate.InitializeDateTimePicker();
            dtMD.InitializeDateTimePicker();
            dtWorkStart.InitializeDateTimePicker();
            dtRecordDate.InitializeDateTimePicker();
        }

        public void Reset()
        {
            InitializeCalendar();

            comMM.SelectedIndex = 0;
            comXL.SelectedIndex = 0;
            comXW.SelectedIndex = 0;
            comSF.SelectedIndex = 0;
            comJSDJ.SelectedIndex = 0;
            comCause.SelectedIndex = 0;

            txtName.Text = String.Empty;
            txtNation.Text = String.Empty;
            txtNativePlace.Text = String.Empty;
            txtFJ.Text = String.Empty;
            txtCollege.Text = String.Empty;
            txtMajor.Text = String.Empty;
            txtHometown.Text = String.Empty;

            txtZW.Text = String.Empty;
            txtZC.Text = String.Empty;
            txtGZ.Text = String.Empty;
            txtGZJB.Text = String.Empty;

            txtUnitIn.Text = String.Empty;
            txtUnitOut.Text = String.Empty;
            lblUnitInId.Text = String.Empty;
            lblUnitOutId.Text = String.Empty;
            txtSQRK.Text = String.Empty;
            txtRemark1.Text = String.Empty;
            txtRemark2.Text = String.Empty;

            _originInUnitType = String.Empty;
            _originOutUnitType = String.Empty;
            _originInUpUnit = String.Empty;
            _originInUnitKind = String.Empty;
            _originOutUnitKind = String.Empty;
            _originOutUpUnit = String.Empty;
        }

        private void InitializeDropDownList()
        {
            comGender.DataSource = new[] { new { Name = "男", Code = "男" }, new { Name = "女", Code = "女" } };
            comGender.DisplayMember = "Name";
            comGender.ValueMember = "Code";
            // 政治面貌     PolicyFace
            DropDownListImpl("PolicyFace", comMM);
            // 学历       SchoolRecord
            DropDownListImpl("SchoolRecord", comXL);
            // 学位       SchoolLevel
            DropDownListImpl("SchoolLevel", comXW);
            // 本人身份     Identity
            DropDownListImpl("Identity", comSF);
            // 技术等级    TechGrade
            DropDownListImpl("TechGrade", comJSDJ);
            // 调动理由    TransCause
            DropDownListImpl("TransCause", comCause);
        }

        private ItemBase GetItemBaseInstance(IRepository repository, int? code)
        {
            if (code.HasValue)
            {
                var item = repository.Find<ItemBase>(code.Value);
                return item;
            }
            return null;
        }

        private Unit GetUnitInstance(IRepository repository, int id)
        {
            var unit = repository.Find<Unit>(id);
            return unit;
        }

        private bool ValidateInputs(out string message)
        {
            message = String.Empty;
            IList<ValidateModel> cl = new List<ValidateModel>
            {
                new ValidateModel{ Control = txtName, Message = "姓名"},
                new ValidateModel{ Control = comGender, Message = "性别"},                
                new ValidateModel{ Control = dtBirthdate, Message = "出生日期"},                
                new ValidateModel{ Control = comXL, Message = "学历"},                
                new ValidateModel{ Control = comSF, Message = "本人身份"},
                // 调入单位
                new ValidateModel{ Control = txtUnitIn, Message = "调入单位"},
                // 调出单位
                new ValidateModel{ Control = txtUnitOut, Message = "调出单位"},

                new ValidateModel{ Control = comCause, Message = "调动理由"},
                new ValidateModel{ Control = dtRecordDate, Message = "填卡时间"}
            };

            if (rdoIn.Checked)
            {
                cl.Add(new ValidateModel { Control = txtNation, Message = "民族" });
                cl.Add(new ValidateModel{ Control = comMM, Message = "政治面貌"});
                cl.Add(new ValidateModel{ Control = dtWorkStart, Message = "参加工作时间"});
            }

            foreach (var c in cl)
            {
                string value = String.Empty;
                if (c.Control is DateTimePickerAdv)
                {
                    var dtp = c.Control as DateTimePickerAdv;
                    if (!dtp.IsNullDate)
                        value = dtp.Value.ToShortDateString();
                }
                if (c.Control is ComboBoxAdv)
                    value = (c.Control as ComboBoxAdv).Text;
                if (c.Control is TextBoxExt)
                    value = (c.Control as TextBoxExt).Text;

                if (IsEmpty(value))
                    message += String.Format("{0} 必填项\r\n", c.Message);
            }

            #region 特殊验证
            // 当选择了干部或聘用制干部在时候，技术等级和从事工种应该不能填内容；而当选择了工勤人员的时候，职称应该不能填内容。
            var sf = comSF.Text;
            if (sf == @"干部" || sf == @"聘用制干部")
            {
                // 从事工种
                // 技术等级
                if (!String.IsNullOrWhiteSpace(txtGZ.Text) || !String.IsNullOrWhiteSpace(comJSDJ.Text))
                {
                    message += String.Format("{0}", @"选择了干部或聘用制干部，技术等级和从事工种应该不能填内容！");
                }
            }
            if (sf == @"工勤人员")
            {
                // 职称
                if (!String.IsNullOrWhiteSpace(txtZC.Text))
                {
                    message += String.Format("{0}", @"当选择了工勤人员，职称应该不能填内容！");
                }
            }
            #endregion
            
            return message == String.Empty ? true : false;
        }

        private void ComSfSelectedIndexChanged(object sender, EventArgs e)
        {
            #region 特殊验证
            // 当选择了干部或聘用制干部在时候，技术等级和从事工种应该不能填内容；而当选择了工勤人员的时候，职称应该不能填内容。
            var sf = comSF.Text;
            if (sf == @"干部" || sf == @"聘用制干部")
            {
                // 从事工种
                // 技术等级
                txtGZ.Text = "";
                txtGZ.Enabled = false;

                comJSDJ.SelectedIndex = 0;
                comJSDJ.ReadOnly = true;
            }
            else
            {
                txtGZ.Enabled = true;
                comJSDJ.ReadOnly = false;
            }
            if (sf == @"工勤人员")
            {
                // 职称
                txtZC.Text = "";
                txtZC.Enabled = false;
            }
            else
            {
                txtZC.Enabled = true;
            }
            #endregion
        }

        private static bool IsEmpty(string content)
        {
            return String.IsNullOrWhiteSpace(content);
        }

        private void BtnOutUnitClick(object sender, EventArgs e)
        {
            var popUp = new ChooseUnit(_repositoryFactory);
            if (DialogResult.OK == popUp.ShowDialog(this))
            {
                txtUnitOut.Text = popUp.SelectedUnit.Name;
                lblUnitOutId.Text = popUp.SelectedUnit.Id.ToString();

                _originOutUpUnit = popUp.SelectedUnit.SuperUnit;
                _originOutUnitKind = popUp.SelectedUnit.UnitKind;
                _originOutUnitType = popUp.SelectedUnit.UnitType;
            }
        }

        private void BtnInUnitClick(object sender, EventArgs e)
        {
            var popUp = new ChooseUnit(_repositoryFactory);
            if (DialogResult.OK == popUp.ShowDialog(this))
            {
                txtUnitIn.Text = popUp.SelectedUnit.Name;
                lblUnitInId.Text = popUp.SelectedUnit.Id.ToString();

                _originInUpUnit = popUp.SelectedUnit.SuperUnit;
                _originInUnitKind = popUp.SelectedUnit.UnitKind;
                _originInUnitType = popUp.SelectedUnit.UnitType;
            }
        }

        private void CollapsePrimitiveCollapsedChanged(object sender, EventArgs e)
        {
            var location = gradientPanelExt1.Location;
            var height = gradientPanelExt1.Height;

            gradientPanelExt2.Location = new Point(location.X, location.Y + height);
            // reset the parent form
            this.ParentForm.Height = height + gradientPanelExt2.Height + 30;
        }        

        // false -> 调入, true ->调出
        private void SetRadioBox(bool inOut)
        {
            rdoIn.Checked = !inOut;
            rdoOut.Checked = inOut;
        }

        private static int GetCode(ItemBase item)
        {
            return item == null ? DefaultNull.DefaultValue : item.Code;
        }

        private void InitializeUpdateView()
        {
            if (!_profileId.HasValue) return;

            using (var repository = _repositoryFactory.CreateRepository())
            {
                var profile = repository.Find<Profile>(_profileId.Value);
                // transferkind settings
                SetRadioBox(profile.TransferKind);

                txtName.Text = profile.Name;
                txtNation.Text = profile.Nationality;

                if (profile.BirthDate.HasValue)
                    dtBirthdate.Value = profile.BirthDate.Value;

                comGender.Text = profile.Gender;
                txtNativePlace.Text = profile.NativePlace;
                comMM.SelectedValue = GetCode(profile.PolicyFace);
                comXL.SelectedValue = GetCode(profile.SchoolRecord);
                comXW.SelectedValue = GetCode(profile.SchoolLevel);
                if (profile.MarriedDate.HasValue)
                    dtMD.Value = profile.MarriedDate.Value;
                txtFJ.Text = profile.Separation;
                txtCollege.Text = profile.College;
                txtMajor.Text = profile.Major;
                txtHometown.Text = profile.HomeTown;
                // 工作信息
                // TODO
                // 调入单位
                txtUnitIn.Text = profile.InUnit.Name;
                lblUnitInId.Text = profile.InUnit.Id.ToString();
                // 调出单位
                txtUnitOut.Text = profile.OutUnit.Name;
                lblUnitOutId.Text = profile.OutUnit.Id.ToString();
                //
                txtZW.Text = profile.ProfPos;
                txtZC.Text = profile.ProfTitle;
                comSF.SelectedValue = GetCode(profile.PersonalIdentity);
                comJSDJ.SelectedValue = GetCode(profile.TechGrade);
                txtGZ.Text = profile.WorkKind;
                if (profile.WorkStart.HasValue)
                    dtWorkStart.Value = profile.WorkStart.Value;
                txtGZJB.Text = profile.SalaryGrade;
                txtSQRK.Text = profile.Family;
                dtRecordDate.Value = profile.RecordDate;
                comCause.SelectedValue = GetCode(profile.TransferReason);
                txtRemark1.Text = profile.Remark1;
                txtRemark2.Text = profile.Remark2;
            }
        }

        private bool GetTransferKind()
        {
            return !rdoIn.Checked;
        }

        public Profile GetProfile(IRepository repository)
        {
             // justify the conditions
            string errors;
            if (!ValidateInputs(out errors))
            {
                LogTrace(errors, MessageType.Error);
                return null;
            }
           
            var profile = _profileId.HasValue ? repository.Find<Profile>(_profileId.Value) : new Profile();
            // 审批结束的数据，其单位信息不能变化
            if (!_profileId.HasValue || profile.ApprovalDate == null)
            {
                profile.OriginalIn = txtUnitIn.Text;
                profile.OriginalOut = txtUnitOut.Text;
           
                if (!String.IsNullOrWhiteSpace(_originInUpUnit))
                    profile.OriginalInUpUnit = _originInUpUnit;
                if (!String.IsNullOrWhiteSpace(_originInUnitType))
                    profile.OriginalInUnitType = _originInUnitType;
                if (!String.IsNullOrWhiteSpace(_originInUnitKind))
                    profile.OriginalInUnitKind = _originInUnitKind;
     
                if (!String.IsNullOrWhiteSpace(_originOutUpUnit))
                    profile.OriginalOutUpUnit = _originOutUpUnit;
                if (!String.IsNullOrWhiteSpace(_originOutUnitType))
                    profile.OriginalOutUnitType = _originOutUnitType;
                if (!String.IsNullOrWhiteSpace(_originOutUnitKind))
                    profile.OriginalOutUnitKind = _originOutUnitKind;
            }
            // 个人信息
            profile.TransferKind = GetTransferKind();

            profile.Name = txtName.Text;
            profile.Nationality = txtNation.Text;
            profile.BirthDate = dtBirthdate.Value.Date;
            profile.Gender = comGender.Text;
            profile.PolicyFace = GetItemBaseInstance(repository, (int)comMM.SelectedValue);
            profile.NativePlace = txtNativePlace.Text;
            profile.SchoolRecord = GetItemBaseInstance(repository, (int)comXL.SelectedValue);
            profile.SchoolLevel = GetItemBaseInstance(repository, (int)comXW.SelectedValue);
            if(!dtMD.IsNullDate)
                profile.MarriedDate = dtMD.Value.Date;
            profile.Separation = txtFJ.Text;
            profile.College = txtCollege.Text;
            profile.Major = txtMajor.Text;
            profile.HomeTown = txtHometown.Text;
            // 工作信息
            // 调入单位
            profile.InUnit = GetUnitInstance(repository, Convert.ToInt16(lblUnitInId.Text));            
            // 调出单位            
            profile.OutUnit = GetUnitInstance(repository, Convert.ToInt16(lblUnitOutId.Text));

            profile.ProfPos = txtZW.Text;
            profile.ProfTitle = txtZC.Text;
            profile.PersonalIdentity = GetItemBaseInstance(repository, (int)comSF.SelectedValue);
            profile.TechGrade = GetItemBaseInstance(repository, (int)comJSDJ.SelectedValue);
            profile.WorkKind = txtGZ.Text;
            if(!dtWorkStart.IsNullDate)
                profile.WorkStart = dtWorkStart.Value.Date;
            else
                profile.WorkStart = null;
            profile.SalaryGrade = txtGZJB.Text;
            profile.Family = txtSQRK.Text;
            profile.RecordDate = dtRecordDate.Value;
            profile.TransferReason = GetItemBaseInstance(repository, (int)comCause.SelectedValue);
            profile.Remark1 = txtRemark1.Text;
            profile.Remark2 = txtRemark2.Text;

            return profile;            
        }

        private void RdoCheckChanged(object sender, EventArgs e)
        {
            if (rdoIn.Checked)
            {
                lblNation.ForeColor = Color.Red;
                lblPolicy.ForeColor = Color.Red;
                lblWorkTime.ForeColor = Color.Red;
            }
            else
            {
                lblNation.ForeColor = SystemColors.ActiveCaption;
                lblPolicy.ForeColor = SystemColors.ActiveCaption;
                lblWorkTime.ForeColor = SystemColors.ActiveCaption;
            }
        }              
    }

    class ValidateModel
    {
        public Control Control { get; set; }
        public string Message { get; set; }
    }

    public class ProfileEventArgs : EventArgs
    {
        public ProfileEventArgs(Profile profile)
        {
            Profile = profile;
        }

        public Profile Profile { get; private set; }
    }

}
